﻿//===========================[ 8 / 1 / 2011 LVI ]=============================
//				Copyright c Vitaly Lyaschenko <SkyChameleon@gmail.com>
//								Source file
// Purpose: стандартные операции над файлами
//=============================================================================
#include "cFile.h"
#include "cwLogger.h"

cFile::cFile( const std::string &fileName, const typeFile type,const modeFile flag ) :
    state(false)
{
	switch( type )
	{
	case fBinary:
		{
			m_mode = flag;
			open_fileAsBinary( fileName );
		} break;

	case fText:
		{
			m_mode = flag;
			open_fileAsText( fileName );
		} break;

	default:
		cwLogger::writeERROR( "File: " + std::string(fileName) + " >> not open!" );
		break;
	}

	cwLogger::writeINFO( "File: " + std::string(fileName) + " >> open success!" );
}

cFile::~cFile()
{   
	if( m_File.is_open() )
		m_File.close();
}

void cFile::open_file( const std::string &fileName, const typeFile type,const modeFile flag )
{
	switch( type )
	{
	case fBinary:
		{
			m_mode = flag;
			open_fileAsBinary( fileName );
		} break;

	case fText:
		{
			m_mode = flag;
			open_fileAsText( fileName );
		} break;

	default:
		cwLogger::writeERROR( "Wrong type open file: " + std::string(fileName) + " !" );
		break;
	}
}

///////////////////////////////////////////////////////////////////////////
// чтение/запись/перезапись текстового файла
void cFile::open_fileAsText( const std::string &fileName )
{
	switch( m_mode )
	{
	case fRead:
		{   // открытие текстового файла для чтения 
			m_File.open( fileName, std::ios::in | std::ios::beg );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot open text file: " + std::string(fileName) );
				break;
			}
			state = true;
		}break;

	case fWrite:
		{   // открытие текстового файла для записи
			m_File.open( fileName, std::ios::out | std::ios::app );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot write to text file: " + std::string(fileName) );
				break;
			}
			state = true;
		}break;

	case fReWrite:
		{    // открытие текстового файла для перезаписи
			m_File.open( fileName, std::ios::out | std::ios::ate );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot rewrite text file: " + std::string(fileName) );
				break;
			}
			state = true;
		}break;

	default:
		{
			state = false;
			cwLogger::writeERROR("Invalid open file as text < " + std::string(fileName) + " > !" );

		} break;
	}
}

///////////////////////////////////////////////////////////////////////////
// чтение/запись/перезапись бинарного файла
void cFile::open_fileAsBinary( const std::string &fileName )
{
	switch( m_mode )
	{
	case fRead:
		{   // открытие бинарного файла для чтения
			m_File.open( fileName, std::ios::in | std::ios::binary | std::ios::beg );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot open binary file: " + std::string(fileName) );
				break;
			}
			state = true;
		} break;

	case fWrite:
		{   // запись в бинарный файл
			m_File.open( fileName, std::ios::out | std::ios::binary |  std::ios::app );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot write to binary file: " + std::string(fileName) );
				break;
			}
			state = true;
		} break;

	case fReWrite:
		{   // перезапись бинарного файла
			m_File.open( fileName, std::ios::out | std::ios::binary |  std::ios::ate );
			if ( !m_File.is_open() )
			{
				state = false;
				cwLogger::writeERROR("cannot rewrite binary file: " + std::string(fileName) );
				break;
			}
			state = true;
		} break;

	default:
		{
			state = false;
			cwLogger::writeERROR("Invalid binary file " + std::string(fileName) + "mode flag!" );
			break;
		} break;
	}
}

///////////////////////////////////////////////////////////////////////////
// перемещение файлового указателя с текущей 
// позиции на указанное количество байт
void cFile::seek( size_t numBytes )
{
	if ( m_File.is_open() )
	{
		m_File.seekg( m_File.tellg(),numBytes );
		m_File.flush();
		state = true;
	}
}
///////////////////////////////////////////////////////////////////////////
// перемещение файлового указателя с начала файла 
// на указанное количество байт
void cFile::seekTo( size_t offset )
{
	if (m_File.is_open())
	{
		m_File.seekg( std::ios_base::beg,offset );
		state = true;
		m_File.flush();
	}
}
///////////////////////////////////////////////////////////////////////////
// возвращает размер файла
long cFile::getSize()
{
	long len;

	if (m_File.is_open())
	{
		//узнаем размер файла, и выделяем память в строке
		m_File.seekg( 0, std::ios_base::end );
		len = m_File.tellg();
		m_File.seekg( 0, std::ios_base::beg );
		state = true;
		return len;
	}
	state = false;
	m_File.flush();
	return -1;
}
///////////////////////////////////////////////////////////////////////////
// возвращает текущую позицию файлового указателя
long cFile::getPosition()
{
	return long( m_File.tellg() );
}
///////////////////////////////////////////////////////////////////////////
// читаети данные в буфер
void cFile::readFile( void *data,size_t numBytes  )
{
	if (m_File.is_open())
	{
		m_File.read( (char*)data,numBytes );
		state = true;
		m_File.flush();
	} else
	state = false;
}

void cFile::writeToFile( void *data,size_t numBytes )
{
	if (m_File.is_open())
	{
		m_File.write( (char*)data, numBytes );
		state = true;
	} else
	state = false;
}